//package cn.com.gc.core.lock;
//
//import RandomUtil;
//import cn.com.gc.core.redis.RedisClusterServer;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//
//
//
//
//public class RedisDistributedLock {
//
//    @Autowired
//    private RedisClusterServer jedis;
//    // 锁的名字
//    protected String lockKey;
//
//    //锁的状态
//    protected  boolean locked;
//
//    // 锁的有效时长(毫秒)
//    protected long lockExpires;
//
//    private final int MILLI_NANO_CONVERSION = 1000;
//
//    public boolean lock(long timeout, int expireSecs) {
//        long nano = System.nanoTime();
//        timeout *= MILLI_NANO_CONVERSION;
//        String lockStart = String.valueOf(System.currentTimeMillis());
//
//        try {
//            while ((System.nanoTime() - nano) < timeout) {
//                if(jedis.setNx(this.lockKey, lockStart,expireSecs)){
//                    this.locked = true;
//                    return this.locked;
//                }
//                // 短暂休眠，避免出现活锁
//                Thread.sleep(3, RandomUtil.nextInt(500));
//            }
//            String expireStr = jedis.get(lockKey);
//            Long now = System.currentTimeMillis();
//            String nowStr = String.valueOf(now);
//            if (!StringUtils.isNumeric(expireStr)){
//                return false;
//            }
//            //ttl小于0 表示key上没有设置生存时间（key是不会不存在的，因为前面setnx会自动创建）
//            //如果出现这种状况，那就是进程的某个实例setnx成功后crash 导致紧跟着的expire没有被调用
//            //这时可以直接设置expire并把锁纳为己用
//            //In Redis 2.6 or older, if the Key does not exists or does not have an associated expire, -1 is returned.
//            //In Redis 2.8 or newer, if the Key does not have an associated expire, -1 is returned or if the Key does not exists, -2 is returned.
//            long ttlValue = jedis.ttl(this.lockKey);
//            if(ttlValue < 0){
//                jedis.setNx(lockKey, nowStr,expireSecs);
//                return true;
//            }
//
//            Long expireLong = Long.parseLong(expireStr);
//            if (now - expireLong > expireSecs * 1000){
//                jedis.del(lockKey);
//                jedis.setNx(lockKey, nowStr,expireSecs);
//                return true;
//            }
//        } catch (Exception e) {
//            throw new RuntimeException("Locking error", e);
//        }
//        return false;
//    }
//
//
//}
